package com.koron.housing.contract.service.impl;


import cn.hutool.core.bean.BeanUtil;
import com.github.pagehelper.PageInfo;
import com.koron.bean.query.PageQuery;
import com.koron.common.core.util.StringUtils;
import com.koron.housing.contract.bean.dto.HousingContractDTO;
import com.koron.housing.contract.bean.param.HousingContractBillParam;
import com.koron.housing.contract.bean.po.HousingContract;
import com.koron.housing.contract.bean.po.HousingContractBill;
import com.koron.housing.contract.bean.po.HousingContractRenewal;
import com.koron.housing.contract.bean.query.ContractQuery;
import com.koron.housing.contract.bean.vo.HousingContractVO;
import com.koron.housing.contract.mapper.HousingContractMapper;
import com.koron.housing.contract.service.HousingContractBillService;
import com.koron.housing.contract.service.HousingContractRenewalService;
import com.koron.housing.contract.service.HousingContractService;
import com.koron.housing.info.bean.po.HousingInfo;
import com.koron.housing.info.service.HousingInfoService;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.*;

/**
 * 合同信息(HousingContract)表服务实现类
 *
 * @author jzp
 * @since 2022-03-07 14:45:16
 */
@Service("contractService")
public class HousingContractServiceImpl implements HousingContractService {

    @Autowired
    private HousingInfoService infoService;
    @Autowired
    private HousingContractBillService billService;
    @Autowired
    private HousingContractRenewalService renewalService;

    /**
     * 通过ID查询单条数据
     */
    @Override
    @TaskAnnotation("getById")
    public HousingContract getById(SessionFactory factory, String id) {
        HousingContractMapper mapper = factory.getMapper(HousingContractMapper.class);
        return mapper.selectById(id);
    }

    @Override
    @TaskAnnotation("getDtoById")
    public HousingContractDTO getDtoById(SessionFactory factory, String id) {
        HousingContract housingContract = getById(factory, id);
        HousingContractDTO housingContractDTO = BeanUtil.toBean(housingContract, HousingContractDTO.class);
        housingContractDTO.setInfoList(infoService.listByContractId(factory, id));
        housingContractDTO.setBillList(billService.listByContractId(factory, id));
        housingContractDTO.setRenewalList(renewalService.listByContractId(factory, id));
        return housingContractDTO;
    }

    @Override
    @TaskAnnotation("list")
    public List<HousingContract> list(SessionFactory factory, ContractQuery query) {
        HousingContractMapper mapper = factory.getMapper(HousingContractMapper.class);
        return mapper.selectList(query);
    }

    /**
     * 查询所有数据
     */
    @Override
    @TaskAnnotation("listVo")
    public List<HousingContractVO> listVo(SessionFactory factory, ContractQuery query) {
        HousingContractMapper mapper = factory.getMapper(HousingContractMapper.class);
        return mapper.selectVoList(query);
    }

    @Override
    @TaskAnnotation("page")
    public PageInfo<HousingContractVO> page(SessionFactory factory, PageQuery pageQuery, ContractQuery query) {
        pageQuery.prefixOrders("housingContract", null);
        return HousingContractService.super.page(factory, pageQuery, query);
    }

    @Override
    @TaskAnnotation("address")
    public List<HousingContract> address(SessionFactory factory) {
        HousingContractMapper mapper = factory.getMapper(HousingContractMapper.class);
        return mapper.groupByField("address");
    }

    @Override
    @TaskAnnotation("village")
    public List<HousingContract> village(SessionFactory factory) {
        HousingContractMapper mapper = factory.getMapper(HousingContractMapper.class);
        return mapper.groupByField("village");
    }

    @Override
    @TaskAnnotation("billCode")
    public List<HousingContract> billCode(SessionFactory factory) {
        HousingContractMapper mapper = factory.getMapper(HousingContractMapper.class);
        return mapper.groupByField("bill_code");
    }

    @Override
    @TaskAnnotation("tenantry")
    public List<HousingContract> tenantry(SessionFactory factory) {
        HousingContractMapper mapper = factory.getMapper(HousingContractMapper.class);
        return mapper.groupByField("tenantry");
    }

    /**
     * 新增数据
     */
    @Override
    @TaskAnnotation("save")
    public boolean save(SessionFactory factory, HousingContract housingContract) {
        // 如果没有状态，则为草稿状态
        if (StringUtils.isEmpty(housingContract.getStatus())) {
            housingContract.setStatus("0");
        }
        // 合同编号不能重复 (台账导入时，如果有重复的合同编号会找不到合同)
        ContractQuery contractQuery = new ContractQuery();
        contractQuery.setCode(housingContract.getCode());
        List<HousingContract> list = list(factory, contractQuery);
        Optional.ofNullable(list).ifPresent(l -> {
            long count = l.stream()
                    .filter(e -> !Objects.equals(e.getId(), housingContract.getId())).count();
            Assert.state(count == 0, "合同编号不能重复");
        });

        HousingContractMapper mapper = factory.getMapper(HousingContractMapper.class);
        return mapper.insertOrUpdate(housingContract) > 0;
    }

    @Override
    @TaskAnnotation("billSubmit")
    public boolean billSubmit(SessionFactory factory, HousingContractBillParam housingContractBillParam) {
        // 查询该财务报销编号下的所有生效合同，并报销
        ContractQuery contractQuery = new ContractQuery();
        contractQuery.setBillCode(housingContractBillParam.getBillCode());
        contractQuery.setStatus(Collections.singletonList("1"));
        List<HousingContract> list = list(factory, contractQuery);
        List<HousingContractBill> collect = new ArrayList<>();
        for (HousingContract housingContract : list) {
            List<HousingInfo> housingInfos = infoService.listByContractId(factory, housingContract.getId());
            for (HousingInfo housingInfo : housingInfos) {
                HousingContractBill housingContractBill = new HousingContractBill();
                housingContractBill.setBillCode(housingContractBillParam.getBillCode());
                housingContractBill.setContractId(housingContract.getId());
                housingContractBill.setContractCode(housingContract.getCode());
                housingContractBill.setHousingId(housingInfo.getId());
                housingContractBill.setRent(housingInfo.getRent());
                housingContractBill.setRoomNum(housingInfo.getRoomNum());
                housingContractBill.setYear(housingContractBillParam.getYear());
                housingContractBill.setMonth(housingContractBillParam.getMonth());
                collect.add(housingContractBill);
            }
        }
        return billService.saveBatch(factory, collect);
    }

    /**
     * 修改数据
     */
    @Override
    @TaskAnnotation("update")
    public boolean update(SessionFactory factory, HousingContract housingContract) {
        HousingContractMapper mapper = factory.getMapper(HousingContractMapper.class);
        return mapper.update(housingContract) > 0;
    }

    @Override
    @TaskAnnotation("renewal")
    public boolean renewal(SessionFactory factory, HousingContract housingContract) {
        // 0. 查询历史信息
        HousingContract source = getById(factory, housingContract.getId());

        // 1. 保存基本信息
        update(factory, housingContract);

        // 2. 续租信息
        HousingContractRenewal housingContractRenewal = new HousingContractRenewal();
        housingContractRenewal.setContractId(source.getId());
        housingContractRenewal.setContractCode(source.getCode());
        housingContractRenewal.setFrameStartTime(source.getFrameStartTime());
        housingContractRenewal.setFrameEndTime(source.getFrameEndTime());
        return renewalService.save(factory, housingContractRenewal);
    }

    /**
     * 通过主键删除数据
     */
    @Override
    @TaskAnnotation("deleteById")
    public boolean deleteById(SessionFactory factory, String id) {
        HousingContractMapper mapper = factory.getMapper(HousingContractMapper.class);
        return mapper.hidden(id) > 0;
    }
}
